#!/usr/bin/env python
################################################################################
#            __  __            _   ____        _ _ ____        _              #
#           |  \/  | ___  __ _| |_| __ )  __ _| | | __ )  ___ | |_           #
#           | |\/| |/ _ \/ _` | __|  _ \ / _` | | |  _ \ / _ \| __|         #
#           | |  | |  __/ (_| | |_| |_) | (_| | | | |_) | (_) | |_          #
#           |_|  |_|\___|\__,_|\__|____/ \__,_|_|_|____/ \___/ \__|          #
#                                                                             #
#                                     by                                       #
# _______ .______       _______  _______   ______   ______   _______   _______  #
#|   ____||   _  \     |   ____||   ____| /      | /  __  \ |       \ |   ____|  #
#|  |__   |  |_)  |    |  |__   |  |__   |  ,----'|  |  |  ||  .--.  ||  |__      #
#|   __|  |      /     |   __|  |   __|  |  |     |  |  |  ||  |  |  ||   __|      #
#|  |     |  |\  \----.|  |____ |  |____ |  `----.|  `--'  ||  '--'  ||  |____      #
#|__|     | _| `._____||_______||_______| \______| \______/ |_______/ |_______|    #
#                                                                                 #
#                               Library Core                                     #
#                             Circuits FrameWork                                #
#
# Coders
#
#	Justin Giorgi (rebel_kid)
#
# Debuggers
#
#	Justin Giorgi (rebel_kid)
#	Lachlan Gilmour (chilli0)
#	David Liedle (spiderbyte)
#	(Polarina)
#	(prologic)
#
################################################################################
#                                                                              #
#                               GPL Licensed                                   #
#                                                                              #
################################################################################

# Imports
from time import time
from decimal import Decimal
from circuits.core import listener, Event, Component

# Sets plugin variables
__id__ = "library"
__core__ = True

# Creates event classes
class Tell(Event): pass
class Log(Event): pass

class Library(Component):
	
	def __init__(self, *args, **kwargs):
		# Important: Call the super constructors to initialize the Component.
		super(Network, self).__init__(*args, **kwargs)
		self.channel = kwargs["channel"]
		self.push(Tell(), "tell", self.channel)
		self.time = str(time())
		self.delay = "0.3"

	# Stores irc instance	
	@listener("tell-reply")
	def onTELLREPLY(self, irc):
		self.irc = irc
		
	# Checks if delay has passed since last send
	def check(self):
		if float(Decimal(self.time) + Decimal(self.delay)) <= time():
			return True
			self.time = str(time())
		else:
			return False
		
	# Relays irc commands
	@listener("issue-raw")
	def onRAW(self, data):
		while True:
			if self.check():
				self.push(Log(action = "RAW", data = data), "log", self.channel)
				self.irc.ircRAW(data)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-server")
	def onSERVER(self, server, hops, token, description):
		while True:
			if self.check():
				self.push(Log(action = "SERVER", server = server, hops = hops, token = token, description = description), "log", self.channel)
				self.irc.ircSERVER(server, hops, token, description)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-user")
	def onUSER(self, ident, host, server, name):
		while True:
			if self.check():
				self.push(Log(action = "USER", ident = ident, host = host, server = server, name = name), "log", self.channel)
				self.irc.ircSERVER(server, hops, token, description)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-nick")
	def onNICK(self, nick, idle=None, signon=None, ident=None, host=None, server=None, hops=None, name=None):
		while True:
			if self.check():
				self.push(Log(action = "NICK", nick = nick, idle = idle, signon = signon, ident = ident, host = host, server = server, hops = hops, name = name), "log", self.channel)
				self.irc.ircNICK(nick, idle, signon, ident, host, server, hops, name)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-ping")
	def onPING(self, server):
		while True:
			if self.check():
				self.push(Log(action = "PING", server = server), "log", self.channel)
				self.irc.ircPING(server)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-pong")
	def onPONG(self, server):
		while True:
			if self.check():
				self.push(Log(action = "PONG", server = server), "log", self.channel)
				self.irc.ircPONG(server)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-quit")
	def onQUIT(self, message="", source=None):
		while True:
			if self.check():
				self.push(Log(action = "QUIT", message = message, source = source), "log", self.channel)
				self.irc.ircQUIT(message, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-join")
	def onJOIN(self, channel, key=None, source=None):
		while True:
			if self.check():
				self.push(Log(action = "JOIN", channel = channel, key = key, source = source), "log", self.channel)
				self.irc.ircJOIN(channel, key, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-part")
	def onPART(self, channel, message="", source=None):
		while True:
			if self.check():
				self.push(Log(action = "PART", channel = channel, message = message, source = source), "log", self.channel)
				self.irc.ircPART(channel, message, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-message")
	def onMESSAGE(self, target, message, source=None):
		while True:
			if self.check():
				self.push(Log(action = "MESSAGE", target = target, message = message, source = source), "log", self.channel)
				self.irc.ircPRIVMSG(channel, message, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-notice")
	def onNOTICE(self, target, message, source=None):
		while True:
			if self.check():
				self.push(Log(action = "NOTICE", target = target, message = message, source = source), "log", self.channel)
				self.irc.ircNOTICE(target, message, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-ctcp")
	def onCTCP(self, target, type, message, source=None):
		while True:
			if self.check():
				self.push(Log(action = "CTCP", target = target, type = type, message = message, source = source), "log", self.channel)
				self.irc.ircCTCP(target, type, message, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-CTCPREPLY)
	def onCTCPREPLY(self, target, type, message, source=None):
		while True:
			if self.check():
				self.push(Log(action = "CTCPREPLY", target = target, type = type, message = message, source = source), "log", self.channel)
				self.irc.ircCTCPREPLY(target, type, message, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-kick")
	def onKICK(self, channel, target, message="", source=None):
		while True:
			if self.check():
				self.push(Log(action = "KICK", channel = channel, target = target, message = message, source = source), "log", self.channel)
				self.irc.ircKICK(channel, target, message, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-topic")
	def onTOPIC(self, channel, topic, whoset=None, whenset=None, source=None):
		while True:
			if self.check():
				self.push(Log(action = "TOPIC", channel = channel, topic = topic, whoset = whoset, whenset = whenset, source = source), "log", self.channel)
				self.irc.ircTOPIC(channel, topic, whoset, whenset, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-mode")
	def onMODE(self, modes, channel=None, source=None):
		while True:
			if self.check():
				self.push(Log(action = "MODE", modes = modes, channel = channel, source = source), "log", self.channel)
				self.irc.ircMODE(modes, channel, source)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-kill")
	def onKILL(self, target, message):
		while True:
			if self.check():
				self.push(Log(action = "KILL", target = target, message = message), "log", self.channel)
				self.irc.ircKILL(target, message)
				break
			else:
				sleep(float(self.delay))
		
	@listener("issue-invite")
	def onINVITE(self, target, channel, source=None):
		while True:
			if self.check():
				self.push(Log(action = "INVITE", target = target, channel = channel, source = source), "log", self.channel)
				self.irc.ircINVITE(target, channel, source)
				break
			else:
				sleep(float(self.delay))
		
def startup(channel, cursor):
	plugin = Library(channel = channel, cursor = cursor)
	return (__id__, plugin)

def kill():
	return __id__
